package com.genericdevice.platform.core.activity;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import com.genericdevice.platform.core.define.EventConstants;
import com.genericdevice.platform.core.event.*;
import com.genericdevice.platform.core.event.listeners.CreateListener;
import com.genericdevice.platform.core.event.listeners.LoadListener;
import com.genericdevice.platform.core.exceptions.UnsupportedOperation;
import com.genericdevice.platform.core.logging.LoggerHelper;
import com.genericdevice.platform.core.menu.OptionsMenuBuilder;
import com.genericdevice.platform.core.menu.OptionsMenuConfig;
import com.genericdevice.platform.core.mvp.AbstractPresenter;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by Xilent on 17.05.2014.
 */
public abstract class AbstractActivity<Presenter extends AbstractPresenter> extends Activity {

    private static LoggerHelper LOGGER = LoggerHelper.getInstance();

    protected OptionsMenuBuilder menuBuilder;
    protected Presenter presenter;
    private List<OptionsMenuConfig> optionsMenuConfigs;
    private Menu menu;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        init();

        EventBus.addListener(EventConstants.MENU_CREATED, new CreateListener(false) {
            @Override
            protected void onCreate(IEvent event) {
                try {
                    menuBuilder.buildItems();

                    try {
                        optionsMenuConfigs = menuBuilder.getOptionsMenuConfigs();
                    } catch (UnsupportedOperation reason) {
                        LOGGER.error("Method \"getOptionsMenuConfigs\" should be called only from default OptionsMenuBuilder", reason);
                    }

                } catch (UnsupportedOperation e) {
                    LOGGER.error("Wrong menu builder created in Activity", e);
                }
            }
        });

        EventBus.fireEvent(EventConstants.PAGE_CREATE);
    }

    protected void init() {
        menuBuilder = OptionsMenuBuilder.getInstance(((Object) this).getClass().getName());

        if (menu != null)
            onCreateOptionsMenu(menu);

        final ProgressDialog loadingDialog = ProgressDialog.show(this, "", "Loading. Please wait...", true);

        EventBus.addListener(EventConstants.PAGE_LOAD, new LoadListener(true) {
            @Override
            protected void onLoad(IEvent event) {
                loadingDialog.dismiss();
            }
        });

        presenter = createPresenter();
        presenter.setActivity(this);
        presenter.init();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        this.menu = menu;
        try {
            menuBuilder.setActivity(this);
            menuBuilder.setCreatedMenu(menu);
            menuBuilder.setMenuInfletter(getMenuInflater());
            menuBuilder.setMenuId(getMenuId());
            Class idsObject = getIdsObject();
            Integer resourceId = getResourceId();
            if (idsObject != null && resourceId != null)
                menuBuilder.setConfigData(resourceId, idsObject);

        } catch (UnsupportedOperation unsupportedOperation) {
            unsupportedOperation.printStackTrace();
        }

        EventBus.fireEvent(EventConstants.MENU_CREATED);

        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        int itemId = item.getItemId();

        String startActivity = null;
        Map<String, String> params = new HashMap<String, String>();
        List<String> events = new ArrayList<String>();
        for (OptionsMenuConfig config : optionsMenuConfigs) {
            String activity = config.getActivity(itemId);
            if (activity != null) {
                startActivity = activity;
                params = config.getParams(itemId);
            }
            String event = config.getEvent(itemId);
            if (event != null && !events.contains(event))
                events.add(event);
        }

        for (String event : events)
            EventBus.fireEvent(event);

        if (startActivity != null) {
            try {
                Class<?> activityClass = Class.forName(startActivity);
                Intent intent = new Intent(this, activityClass);

                if (params.size() > 0) {
                    Bundle bundle = new Bundle();
                    for (Map.Entry<String, String> param : params.entrySet()) {
                        bundle.putString(param.getKey(), param.getValue());
                    }
                    intent.putExtras(bundle);
                }

                startActivity(intent);
            } catch (ClassNotFoundException e) {
                LOGGER.error("Can not find class: " + startActivity, e);
            }
        }

        return true;
    }

    protected abstract Presenter createPresenter();

    protected abstract int getMenuId();

    protected Integer getResourceId() {
        return null;
    }

    protected Class getIdsObject() {
        return null;
    }

    @Override
    public void finish() {
        presenter.destory();

        try {
            menuBuilder.clearBuilders();
        } catch (UnsupportedOperation e) {
            LOGGER.error("Wrong menu builder created in Activity", e);
        }

        super.finish();
        getIntent().setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
    }
}
